package cn.wolfcode.service.impl;

import cn.wolfcode.domain.Permission;
import cn.wolfcode.mapper.PermissionMapper;
import cn.wolfcode.qo.QueryObject;
import cn.wolfcode.service.IPermissionService;
import cn.wolfcode.util.RequiredPermission;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.*;

@Service
public class PermissionServiceImpl implements IPermissionService {

    //获取所有控制器对象
    @Autowired
    private RequestMappingHandlerMapping rmhm;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void reload() {

        //从数据库中查询所有上了权限的方法
        List<Permission> permissions = permissionMapper.selectAll();
        //把方法的表达式放到Set集合中
        Set<String> expressionSet = new HashSet<>();
        for (Permission permission:permissions){
            expressionSet.add(permission.getExpression());
        }


        //获取所有贴了映射路劲的方法
        // RequestMappingInfo:映射路劲
        //HandlerMethod: 映射路劲对应的方法
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = rmhm.getHandlerMethods();
        //获取所有控制器里面的所有方法
        Collection<HandlerMethod> values = handlerMethods.values();
        for (HandlerMethod value : values){
            //获取方法上RequiredPermission的注解
            RequiredPermission methodAnnotation = value.getMethodAnnotation(RequiredPermission.class);
            if (methodAnnotation!=null){
                //获取方法上注解的表达式
                String expression = methodAnnotation.expression();
                //如果集合中不包含该表达式,则添加到数据库中
                if (!expressionSet.contains(expression)){
                    Permission p = new Permission();
                    p.setName(methodAnnotation.name());
                    p.setExpression(methodAnnotation.expression());
                    permissionMapper.insert(p);
                }
                //否则在容器中删除该表达式
                else {
                    expressionSet.remove(expression);
                }
            }
        }
        //此时若容器中还存在表达式,证明该表达式已经不需要权限访问,则在数据库中进行删除
        for (String expression : expressionSet){
            permissionMapper.delete(expression);
        }

    }

    @Override
    public PageInfo<Permission> query(QueryObject qo) {
        PageHelper.startPage(qo.getCurrentPage(),qo.getPageSize());
        List<Permission> list = permissionMapper.query(qo);
        return new PageInfo<>(list);
    }

    @Override
    public List<Permission> list() {
        return permissionMapper.selectAll();
    }

    @Override
    public List<Permission> selectRelation(Long id) {
        return permissionMapper.selectRelation(id);
    }
}
